home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / lib / ruby / 1.8 / open3.rb < prev    next >
Encoding:
Ruby Source  |  2009-12-13  |  2.1 KB  |  108 lines

  1. #
  2. # = open3.rb: Popen, but with stderr, too
  3. #
  4. # Author:: Yukihiro Matsumoto
  5. # Documentation:: Konrad Meyer
  6. #
  7. # Open3 gives you access to stdin, stdout, and stderr when running other
  8. # programs.
  9. #
  10.  
  11. #
  12. # Open3 grants you access to stdin, stdout, and stderr when running another
  13. # program. Example:
  14. #
  15. #   require "open3"
  16. #   include Open3
  17. #   
  18. #   stdin, stdout, stderr = popen3('nroff -man')
  19. #
  20. # Open3.popen3 can also take a block which will receive stdin, stdout and
  21. # stderr as parameters.  This ensures stdin, stdout and stderr are closed
  22. # once the block exits. Example:
  23. #
  24. #   require "open3"
  25. #
  26. #   Open3.popen3('nroff -man') { |stdin, stdout, stderr| ... }
  27. #
  28.  
  29. module Open3
  30.   # 
  31.   # Open stdin, stdout, and stderr streams and start external executable.
  32.   # Non-block form:
  33.   #   
  34.   #   require 'open3'
  35.   #
  36.   #   stdin, stdout, stderr = Open3.popen3(cmd)
  37.   #
  38.   # Block form:
  39.   #
  40.   #   require 'open3'
  41.   #
  42.   #   Open3.popen3(cmd) { |stdin, stdout, stderr| ... }
  43.   #
  44.   # The parameter +cmd+ is passed directly to Kernel#exec.
  45.   #
  46.   # _popen3_ is like _system_ in that you can pass extra parameters, and the
  47.   # strings won't be mangled by shell expansion.
  48.   #
  49.   #   stdin, stdout, stderr = Open3.popen3('identify', '/weird path/with spaces/and "strange" characters.jpg')
  50.   #   result = stdout.read
  51.   #
  52.   def popen3(*cmd)
  53.     pw = IO::pipe   # pipe[0] for read, pipe[1] for write
  54.     pr = IO::pipe
  55.     pe = IO::pipe
  56.  
  57.     pid = fork{
  58.       # child
  59.       fork{
  60.     # grandchild
  61.     pw[1].close
  62.     STDIN.reopen(pw[0])
  63.     pw[0].close
  64.  
  65.     pr[0].close
  66.     STDOUT.reopen(pr[1])
  67.     pr[1].close
  68.  
  69.     pe[0].close
  70.     STDERR.reopen(pe[1])
  71.     pe[1].close
  72.  
  73.     exec(*cmd)
  74.       }
  75.       exit!(0)
  76.     }
  77.  
  78.     pw[0].close
  79.     pr[1].close
  80.     pe[1].close
  81.     Process.waitpid(pid)
  82.     pi = [pw[1], pr[0], pe[0]]
  83.     pw[1].sync = true
  84.     if defined? yield
  85.       begin
  86.     return yield(*pi)
  87.       ensure
  88.     pi.each{|p| p.close unless p.closed?}
  89.       end
  90.     end
  91.     pi
  92.   end
  93.   module_function :popen3
  94. end
  95.  
  96. if $0 == __FILE__
  97.   a = Open3.popen3("nroff -man")
  98.   Thread.start do
  99.     while line = gets
  100.       a[0].print line
  101.     end
  102.     a[0].close
  103.   end
  104.   while line = a[1].gets
  105.     print ":", line
  106.   end
  107. end
  108.